Passed
Pull Request — master (#57)
by
unknown
11:34 queued 08:49
created

collapse.js ➔ show   D

Complexity

Conditions 13

Size

Total Lines 73
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 41
c 0
b 0
f 0
dl 0
loc 73
rs 4.2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like collapse.js ➔ show often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*!
2
  * Bootstrap collapse.js v4.6.1 (https://getbootstrap.com/)
3
  * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
  */
6
(function (global, factory) {
7
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) :
8
  typeof define === 'function' && define.amd ? define(['jquery', './util'], factory) :
9
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Collapse = factory(global.jQuery, global.Util));
10
})(this, (function ($, Util) { 'use strict';
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
14
  var $__default = /*#__PURE__*/_interopDefaultLegacy($);
15
  var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util);
16
17
  function _defineProperties(target, props) {
18
    for (var i = 0; i < props.length; i++) {
19
      var descriptor = props[i];
20
      descriptor.enumerable = descriptor.enumerable || false;
21
      descriptor.configurable = true;
22
      if ("value" in descriptor) descriptor.writable = true;
23
      Object.defineProperty(target, descriptor.key, descriptor);
24
    }
25
  }
26
27
  function _createClass(Constructor, protoProps, staticProps) {
28
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
29
    if (staticProps) _defineProperties(Constructor, staticProps);
30
    return Constructor;
31
  }
32
33
  function _extends() {
34
    _extends = Object.assign || function (target) {
35
      for (var i = 1; i < arguments.length; i++) {
36
        var source = arguments[i];
37
38
        for (var key in source) {
39
          if (Object.prototype.hasOwnProperty.call(source, key)) {
40
            target[key] = source[key];
41
          }
42
        }
43
      }
44
45
      return target;
46
    };
47
48
    return _extends.apply(this, arguments);
49
  }
50
51
  /**
52
   * Constants
53
   */
54
55
  var NAME = 'collapse';
56
  var VERSION = '4.6.1';
57
  var DATA_KEY = 'bs.collapse';
58
  var EVENT_KEY = "." + DATA_KEY;
59
  var DATA_API_KEY = '.data-api';
60
  var JQUERY_NO_CONFLICT = $__default["default"].fn[NAME];
61
  var CLASS_NAME_SHOW = 'show';
62
  var CLASS_NAME_COLLAPSE = 'collapse';
63
  var CLASS_NAME_COLLAPSING = 'collapsing';
64
  var CLASS_NAME_COLLAPSED = 'collapsed';
65
  var DIMENSION_WIDTH = 'width';
66
  var DIMENSION_HEIGHT = 'height';
67
  var EVENT_SHOW = "show" + EVENT_KEY;
68
  var EVENT_SHOWN = "shown" + EVENT_KEY;
69
  var EVENT_HIDE = "hide" + EVENT_KEY;
70
  var EVENT_HIDDEN = "hidden" + EVENT_KEY;
71
  var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY;
72
  var SELECTOR_ACTIVES = '.show, .collapsing';
73
  var SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]';
74
  var Default = {
75
    toggle: true,
76
    parent: ''
77
  };
78
  var DefaultType = {
79
    toggle: 'boolean',
80
    parent: '(string|element)'
81
  };
82
  /**
83
   * Class definition
84
   */
85
86
  var Collapse = /*#__PURE__*/function () {
87
    function Collapse(element, config) {
88
      this._isTransitioning = false;
89
      this._element = element;
90
      this._config = this._getConfig(config);
91
      this._triggerArray = [].slice.call(document.querySelectorAll("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]")));
92
      var toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE));
93
94
      for (var i = 0, len = toggleList.length; i < len; i++) {
95
        var elem = toggleList[i];
96
        var selector = Util__default["default"].getSelectorFromElement(elem);
97
        var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) {
98
          return foundElem === element;
99
        });
100
101
        if (selector !== null && filterElement.length > 0) {
102
          this._selector = selector;
103
104
          this._triggerArray.push(elem);
105
        }
106
      }
107
108
      this._parent = this._config.parent ? this._getParent() : null;
109
110
      if (!this._config.parent) {
111
        this._addAriaAndCollapsedClass(this._element, this._triggerArray);
112
      }
113
114
      if (this._config.toggle) {
115
        this.toggle();
116
      }
117
    } // Getters
118
119
120
    var _proto = Collapse.prototype;
121
122
    // Public
123
    _proto.toggle = function toggle() {
124
      if ($__default["default"](this._element).hasClass(CLASS_NAME_SHOW)) {
125
        this.hide();
126
      } else {
127
        this.show();
128
      }
129
    };
130
131
    _proto.show = function show() {
132
      var _this = this;
133
134
      if (this._isTransitioning || $__default["default"](this._element).hasClass(CLASS_NAME_SHOW)) {
135
        return;
136
      }
137
138
      var actives;
139
      var activesData;
140
141
      if (this._parent) {
142
        actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES)).filter(function (elem) {
143
          if (typeof _this._config.parent === 'string') {
144
            return elem.getAttribute('data-parent') === _this._config.parent;
145
          }
146
147
          return elem.classList.contains(CLASS_NAME_COLLAPSE);
148
        });
149
150
        if (actives.length === 0) {
151
          actives = null;
152
        }
153
      }
154
155
      if (actives) {
156
        activesData = $__default["default"](actives).not(this._selector).data(DATA_KEY);
157
158
        if (activesData && activesData._isTransitioning) {
159
          return;
160
        }
161
      }
162
163
      var startEvent = $__default["default"].Event(EVENT_SHOW);
164
      $__default["default"](this._element).trigger(startEvent);
165
166
      if (startEvent.isDefaultPrevented()) {
167
        return;
168
      }
169
170
      if (actives) {
171
        Collapse._jQueryInterface.call($__default["default"](actives).not(this._selector), 'hide');
172
173
        if (!activesData) {
174
          $__default["default"](actives).data(DATA_KEY, null);
175
        }
176
      }
177
178
      var dimension = this._getDimension();
179
180
      $__default["default"](this._element).removeClass(CLASS_NAME_COLLAPSE).addClass(CLASS_NAME_COLLAPSING);
181
      this._element.style[dimension] = 0;
182
183
      if (this._triggerArray.length) {
184
        $__default["default"](this._triggerArray).removeClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', true);
185
      }
186
187
      this.setTransitioning(true);
188
189
      var complete = function complete() {
190
        $__default["default"](_this._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW);
191
        _this._element.style[dimension] = '';
192
193
        _this.setTransitioning(false);
194
195
        $__default["default"](_this._element).trigger(EVENT_SHOWN);
196
      };
197
198
      var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
199
      var scrollSize = "scroll" + capitalizedDimension;
200
      var transitionDuration = Util__default["default"].getTransitionDurationFromElement(this._element);
201
      $__default["default"](this._element).one(Util__default["default"].TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
202
      this._element.style[dimension] = this._element[scrollSize] + "px";
203
    };
204
205
    _proto.hide = function hide() {
206
      var _this2 = this;
207
208
      if (this._isTransitioning || !$__default["default"](this._element).hasClass(CLASS_NAME_SHOW)) {
209
        return;
210
      }
211
212
      var startEvent = $__default["default"].Event(EVENT_HIDE);
213
      $__default["default"](this._element).trigger(startEvent);
214
215
      if (startEvent.isDefaultPrevented()) {
216
        return;
217
      }
218
219
      var dimension = this._getDimension();
220
221
      this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px";
222
      Util__default["default"].reflow(this._element);
223
      $__default["default"](this._element).addClass(CLASS_NAME_COLLAPSING).removeClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW);
224
      var triggerArrayLength = this._triggerArray.length;
225
226
      if (triggerArrayLength > 0) {
227
        for (var i = 0; i < triggerArrayLength; i++) {
228
          var trigger = this._triggerArray[i];
229
          var selector = Util__default["default"].getSelectorFromElement(trigger);
230
231
          if (selector !== null) {
232
            var $elem = $__default["default"]([].slice.call(document.querySelectorAll(selector)));
233
234
            if (!$elem.hasClass(CLASS_NAME_SHOW)) {
235
              $__default["default"](trigger).addClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', false);
236
            }
237
          }
238
        }
239
      }
240
241
      this.setTransitioning(true);
242
243
      var complete = function complete() {
244
        _this2.setTransitioning(false);
245
246
        $__default["default"](_this2._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE).trigger(EVENT_HIDDEN);
247
      };
248
249
      this._element.style[dimension] = '';
250
      var transitionDuration = Util__default["default"].getTransitionDurationFromElement(this._element);
251
      $__default["default"](this._element).one(Util__default["default"].TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
252
    };
253
254
    _proto.setTransitioning = function setTransitioning(isTransitioning) {
255
      this._isTransitioning = isTransitioning;
256
    };
257
258
    _proto.dispose = function dispose() {
259
      $__default["default"].removeData(this._element, DATA_KEY);
260
      this._config = null;
261
      this._parent = null;
262
      this._element = null;
263
      this._triggerArray = null;
264
      this._isTransitioning = null;
265
    } // Private
266
    ;
267
268
    _proto._getConfig = function _getConfig(config) {
269
      config = _extends({}, Default, config);
270
      config.toggle = Boolean(config.toggle); // Coerce string values
271
272
      Util__default["default"].typeCheckConfig(NAME, config, DefaultType);
273
      return config;
274
    };
275
276
    _proto._getDimension = function _getDimension() {
277
      var hasWidth = $__default["default"](this._element).hasClass(DIMENSION_WIDTH);
278
      return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT;
279
    };
280
281
    _proto._getParent = function _getParent() {
282
      var _this3 = this;
283
284
      var parent;
285
286
      if (Util__default["default"].isElement(this._config.parent)) {
287
        parent = this._config.parent; // It's a jQuery object
288
289
        if (typeof this._config.parent.jquery !== 'undefined') {
290
          parent = this._config.parent[0];
291
        }
292
      } else {
293
        parent = document.querySelector(this._config.parent);
294
      }
295
296
      var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]";
297
      var children = [].slice.call(parent.querySelectorAll(selector));
298
      $__default["default"](children).each(function (i, element) {
299
        _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
300
      });
301
      return parent;
302
    };
303
304
    _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {
305
      var isOpen = $__default["default"](element).hasClass(CLASS_NAME_SHOW);
306
307
      if (triggerArray.length) {
308
        $__default["default"](triggerArray).toggleClass(CLASS_NAME_COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
309
      }
310
    } // Static
311
    ;
312
313
    Collapse._getTargetFromElement = function _getTargetFromElement(element) {
314
      var selector = Util__default["default"].getSelectorFromElement(element);
315
      return selector ? document.querySelector(selector) : null;
316
    };
317
318
    Collapse._jQueryInterface = function _jQueryInterface(config) {
319
      return this.each(function () {
320
        var $element = $__default["default"](this);
321
        var data = $element.data(DATA_KEY);
322
323
        var _config = _extends({}, Default, $element.data(), typeof config === 'object' && config ? config : {});
324
325
        if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
326
          _config.toggle = false;
327
        }
328
329
        if (!data) {
330
          data = new Collapse(this, _config);
331
          $element.data(DATA_KEY, data);
332
        }
333
334
        if (typeof config === 'string') {
335
          if (typeof data[config] === 'undefined') {
336
            throw new TypeError("No method named \"" + config + "\"");
337
          }
338
339
          data[config]();
340
        }
341
      });
342
    };
343
344
    _createClass(Collapse, null, [{
345
      key: "VERSION",
346
      get: function get() {
347
        return VERSION;
348
      }
349
    }, {
350
      key: "Default",
351
      get: function get() {
352
        return Default;
353
      }
354
    }]);
355
356
    return Collapse;
357
  }();
358
  /**
359
   * Data API implementation
360
   */
361
362
363
  $__default["default"](document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
364
    // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
365
    if (event.currentTarget.tagName === 'A') {
366
      event.preventDefault();
367
    }
368
369
    var $trigger = $__default["default"](this);
370
    var selector = Util__default["default"].getSelectorFromElement(this);
371
    var selectors = [].slice.call(document.querySelectorAll(selector));
372
    $__default["default"](selectors).each(function () {
373
      var $target = $__default["default"](this);
374
      var data = $target.data(DATA_KEY);
375
      var config = data ? 'toggle' : $trigger.data();
376
377
      Collapse._jQueryInterface.call($target, config);
378
    });
379
  });
380
  /**
381
   * jQuery
382
   */
383
384
  $__default["default"].fn[NAME] = Collapse._jQueryInterface;
385
  $__default["default"].fn[NAME].Constructor = Collapse;
386
387
  $__default["default"].fn[NAME].noConflict = function () {
388
    $__default["default"].fn[NAME] = JQUERY_NO_CONFLICT;
389
    return Collapse._jQueryInterface;
390
  };
391
392
  return Collapse;
393
394
}));
395
//# sourceMappingURL=collapse.js.map
396